<template>
  <div>
    <el-tree
      ref="SlotTree"
      :data="setTree"
      :props="defaultProps"
      highlight-current
      :expand-on-click-node="true"
      :node-key="NODE_KEY"
    >
      <!-- default-expand-all -->
      <div class="comp-tr-node" slot-scope="{ node, data }">
        <!-- 编辑状态 -->
        <template v-if="node.isEdit">
          <el-input
            class="ipt"
            v-model="data.label"
            autofocus
            size="mini"
            :ref="'slotTreeInput' + data[NODE_KEY]"
            @blur.stop="handleInput(node, data)"
            @keyup.enter.native="handleInput(node, data)"
          ></el-input>
        </template>
        <!-- 非编辑状态 -->
        <template v-else>
          <!-- 名称： 新增节点增加class（is-new） -->
          <!-- <span
            :class="[
              data[NODE_KEY] < NODE_ID_START ? 'is-new' : '',
              'comp-tr-node--name',
            ]"
          > -->
          <i class="iconfont icon-ganbu"></i>
          <span class="comp-tr-node--name">
            <span>{{ data.jgMc }}</span>
          </span>
          <!-- 按钮 -->
          <span class="comp-tr-node--btns">
            <!-- 新增 -->
            <i class="el-icon-plus" @click="handleAdd(node, data)"></i>
            <!-- 编辑 -->
            <i class="el-icon-edit" @click="handleEdit(node, data)"></i>
            <!-- 删除 -->
            <i class="el-icon-delete" @click="handleDelete(node, data)"></i>
          </span>
        </template>
      </div>
    </el-tree>

    <div class="mt-20">每个父节点只能选择一个子节点</div>
    <div class="trees-box">
      <!-- 每个父节点只能选择一个子节点 -->
      <el-tree
        :data="treeData"
        show-checkbox
        node-key="id"
        ref="trees"
        check-strictly
        @check="handelCheck"
        :props="defaultProps2"
        @check-change="handleCheckChange"
        check-on-click-node
      >
      </el-tree>

      <div class="name-box">
        <ul>
          <li v-for="item in checkedNodes" :key="item.id">{{ item.name }}</li>
        </ul>
      </div>

      <!-- {{ checkedNodes }} -->
    </div>
    <el-button @click="getCurrentTree">获取当前选中节点</el-button>
    <el-button @click="clearCurrentTree">清除当前选中节点</el-button>
  </div>
</template>
<script>
export default {
  data() {
    return {
      backupsMode: false,
      signTree: false, //判断tree是新增还是修改
      setTree: [
        {
          id: 1,
          jgMc: "一级 1",
          children: [
            {
              id: 4,
              jgMc: "二级 1-1",
              parentId: 1,
              // children: [{
              //   id: 9,
              //   jgMc: '三级 1-1-1',
              // }, {
              //   id: 10,
              //   jgMc: '三级 1-1-2',
              // }]
            },
          ],
        },
        {
          id: 2,
          jgMc: "一级 2",
          children: [
            {
              id: 5,
              jgMc: "二级 2-1",
              parentId: 2,
            },
            {
              id: 6,
              jgMc: "二级 2-2",
              parentId: 2,
            },
          ],
        },
        {
          id: 3,
          jgMc: "一级 3",
          children: [
            {
              id: 7,
              jgMc: "二级 3-1",
              parentId: 3,
            },
            {
              id: 8,
              jgMc: "二级 3-2",
              parentId: 3,
            },
          ],
        },
      ], // tree数据
      NODE_KEY: "id", // id对应字段
      MAX_LEVEL: 4, // 设定最大层级
      NODE_ID_START: 0, // 新增节点id，逐次递减
      startId: null,
      defaultProps: {
        // 默认设置
        // children: "jg",
        label: "jgMc",
      },
      initParam: {
        // 新增参数
        jgMc: "请填写备件库名",
        pid: 0,
        children: [],
      },
      defaultProps2: {
        // 默认设置
        // children: "jg",
        label: "name",
      },
      treeData: [       // 第二颗tree的数据
        {
          id: 1,
          name: "一级 1",
          children: [
            {
              id: 4,
              name: "二级 1-1",
              parentId: 1,
            },
            // {
            //   id: 9,
            //   name: "二级 1-2",
            //   parentId: 1,
            // },
          ],
        },
        {
          id: 2,
          name: "一级 2",
          children: [
            {
              id: 5,
              name: "二级 2-1",
              parentId: 2,
            },
            {
              id: 6,
              name: "二级 2-2",
              parentId: 2,
            },
          ],
        },
        {
          id: 3,
          name: "一级 3",
          children: [
            {
              id: 7,
              name: "二级 3-1",
              parentId: 3,
            },
            {
              id: 8,
              name: "二级 3-2",
              parentId: 3,
            },
          ],
        },
      ], // tree数据
      currentParent: [], // 储存选中节点的父节点id
      checkedNodes: [], // 当前选中的节点node
      currentNodeArr: [],
    };
  },
  mounted() {
    console.log();
  },
  methods: {
    getCurrentTree(node, val, old) {
      // console.log("🚀 ~ file: tree.vue ~ line 202 ~ parentModules ~ this.$refs.tree.getCheckedKeys()", this.$refs.trees.getHalfCheckedNodes())
      this.$refs.trees.setChecked(8, false);
    },
    clearCurrentTree() {
      this.$refs.trees.setCheckedKeys([]);
    },

    handelCheck(node, nodeObj) {
      // // 储存当前选中的节点数组,要设置check-strictly为true(父节点与子节点不关联),否则只有一个子节点的时候,父节点也会被选上,不设置check-strictly的话,就要用下面的方式
      this.checkedNodes = nodeObj.checkedNodes;

      // 不设置check-strictly,但只有一个子节点时,也不选中父节点
      // this.checkedNodes = nodeObj.checkedNodes.filter(item => {
      //   return !item.children
      // });

      // 因为设置了check-on-click-node(点击节点就选中),父节点也会被选中,所以要去掉父节点的数据
      this.checkedNodes = this.checkedNodes.filter(item=>{
        return !item.children
      })
    },
    handleCheckChange(node, checked, val) {
      // 选中节点时
      if (checked && !node.children) {
        // 该父节点下的子节点第一次被选中,因为是第一次,所以该父节点不会存在两个子节点被选中,
        if (this.currentParent.indexOf(node.parentId) === -1) {  // 如果!= -1,说明该父节点下有其他子节点已被选中
          // 记录父节点
          this.currentParent.push(node.parentId);
        } else {
          // 如果是节点取消选中,则不作处理
          if (this.checkedNodes && this.checkedNodes.length === 0) {
            return;
          }

          // 已有子节点选中,则替换掉最新选中的节点
          for (let i = 0; i < this.checkedNodes.length; i++) {
            if (node.parentId === this.checkedNodes[i].parentId) {
              // 把同个父节点下已勾选的节点变为不选中
              this.$refs.trees.setChecked(this.checkedNodes[i].id, false);
              // 替换掉同个父节点下已勾选的节点
              this.checkedNodes.splice(i, 1, node);
            }
          }
        }
      }
    },

    // 优化前
    // handleCheckChange(node, checked, val){
    //   if(checked && !node.children) {
    //     if(this.currentParent.indexOf(node.parentId) === -1) {
    //       this.currentParent.push(node.parentId)
    //       this.currentNodeArr.push(node)
    //     } else {
    //       if (this.checkedNodes && this.checkedNodes.length === 0) {
    //         return
    //       }
    //       // 更新已勾选的节点数组
    //       this.currentNodeArr = this.checkedNodes;

    //       for (let i = 0; i < this.currentNodeArr.length; i++) {
    //         if(node.parentId === this.currentNodeArr[i].parentId) {
    //           // 把同个父节点下已勾选的节点变为不选中
    //           this.$refs.trees.setChecked(this.currentNodeArr[i].id, false);
    //           // 替换掉同个父节点下已勾选的节点
    //           this.currentNodeArr.splice(i, 1, node);
    //         }
    //       }
    //     }
    //   }
    // },
    // 删除节点
    handleDelete(_node, _data) {
      console.log(_node, _data);
      // 判断是否存在子节点
      if (_data.jg && _data.jg.length !== 0) {
        this.$message.error("此节点有子级，不可删除！");
        return false;
      } else {
        // 删除操作
        let DeletOprate = () => {
          this.$refs.SlotTree.remove(_data);
          //这个可以填写删除当前数据的接口
        };
        // 二次确认
        let ConfirmFun = () => {
          this.$confirm("是否删除此节点？", "提示", {
            confirmButtonText: "确认",
            cancelButtonText: "取消",
            type: "warning",
          })
            .then(() => {
              DeletOprate();
            })
            .catch(() => {});
        };
        // 判断是否新增：新增节点直接删除，已存在的节点要二次确认
        _data[this.NODE_KEY] < this.NODE_ID_START
          ? DeletOprate()
          : ConfirmFun();
      }
    },
    // 修改节点
    handleInput(_node, _data) {
      console.log(_node, _data);
      if (_node.isEdit) {
        this.$set(_node, "isEdit", false);
        // 填写修改节点的接口
      }
    },
    // 编辑节点
    handleEdit(_node, _data) {
      console.log(_node, _data);
      if (!_node.isEdit) {
        this.$set(_node, "isEdit", true);
      }
      // 输入框聚焦
      this.$nextTick(() => {
        if (this.$refs["slotTreeInput" + _data[this.NODE_KEY]]) {
          this.$refs[
            "slotTreeInput" + _data[this.NODE_KEY]
          ].$refs.input.focus();
        }
      });
    },
    // 新增节点
    handleAdd(_node, _data) {
      console.log(_node, _data);
      // 判断层级
      if (_node.level >= this.MAX_LEVEL) {
        this.$message.warning("当前已达到" + this.MAX_LEVEL + "级，无法新增！");
        return false;
      }
      // 参数修改
      let obj = JSON.parse(JSON.stringify(this.initParam)); // copy参数
      console.log(obj);
      obj.pid = _data.jgId; // 父id
      obj[this.NODE_KEY] = ++this.startId; // 节点id：逐次递增id
      // 判断字段是否存在
      if (!_data.jg) {
        this.$set(_data, "jg", []);
      }
      // 新增数据
      _data.jg.push(obj);
      // 展开节点
      // _node.expanded = true
      if (!_node.expanded) {
        _node.expanded = true;
      }
    },
    // 添加顶部节点
    handleAddTop() {
      let obj = JSON.parse(JSON.stringify(this.initParam)); // copy参数
      obj[this.NODE_KEY] = ++this.startId; // 节点id：逐次递增id
      this.setTree.push(obj);
      console.log(this.setTree);
    },
  },
};
</script>
<style lang="less" scoped>
.ipt {
  margin-top: 8px;
}
.tree-box /deep/ .el-tree-node {
  line-height: 45px;
}
.tree-box /deep/ .el-tree-node__content {
  height: 45px;
  line-height: 45px;
}
.comp-tr-top {
  margin-left: 10%;
}
.comp-tr-node {
  height: 45px;
}
.comp-tr-node /deep/ .is-new {
  font-weight: bold;
}
.comp-tr-node /deep/ .comp-tr-node--name {
  //   width:270px;
  margin-right: 20px;
  display: inline-block;
  line-height: 45px;
}
.tree-box /deep/ .el-tree-node__expand-icon {
  font-size: 26px;
}
.comp-tr-node--btns {
  opacity: 0;
  i {
    margin-right: 10px;
  }
}
.el-tree-node__content:hover .comp-tr-node--btns {
  opacity: 1;
}

.trees-box {
  display: flex;
  // 隐藏父节点复选框
  ::v-deep .el-tree-node__content {
    .el-checkbox__inner {
      display: none;
    }
  }
  ::v-deep .el-tree-node__children {
    .el-checkbox__inner {
      display: block;
    }
  }

  .name-box {
    margin-left: 200px;
    ul > li {
      // display: inline-block;
    }
  }
}
</style>
